

import java.awt.BorderLayout;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.AbstractMap.SimpleEntry;
import java.util.Map.Entry;

import javax.swing.JFrame;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class ToolBox {
	public static final double MOVEMENT_THRESHOLD = 1.0;
	
	public static final String[] pathnames = {
		"../DW128-sampling50ms/walk-slow-paul-1345627864337.dat", // 0
		"../DW128-sampling50ms/walk-normal-paul-1345627947728.dat", // 1
		"../DW128-sampling50ms/walk-paul-1345628278491.dat", // 2
		"../DW128-sampling50ms/run-slow-paul-1345628111981.dat", // 3
		"../DW128-sampling50ms/walk-fast-paul-1345628028077.dat", // 4
		"../DW128-sampling50ms/run-fast-paul-1345628215881.dat", // 5
		"../DW128-sampling50ms/downstairs-paul-1345662536191.dat", // 6
		"../DW128-sampling50ms/downstairs-paul-1345662429121.dat", // 7
		"../DW128-sampling50ms/downstairs-mat-1345662917977.dat", // 8
		"../DW128-sampling50ms/upstairs-paul-1345657800224.dat", // 9
		"../DW128-sampling50ms/upstairs-paul-1345662390475.dat", // 10
		"../DW128-sampling50ms/walkslow-mat-1345663579961.dat", // 11
		"../DW128-sampling50ms/walknormal-mat-1345663675541.dat", // 12
		"../DW128-sampling50ms/walkfast-mat-1345663863309.dat", // 13
		"../DW128-sampling50ms/run-mat-1345663788218.dat", // 14
	};
	
	// In trained dataset
//	static final String pathname = "../running slow-1340194130006.dat";
//	static final String pathname2 = "../walk nornal-1340193841822.dat";
//	static final String pathname3 = "../walk fast-1340193945575.dat";
//	static final String pathname4 = "../whar-1340032509641.dat";
//	static final String pathname5 = "../walk slow-1340362638575.dat";
//	static final String pathname6 = "../run normal-1340362395710.dat";
//	static final String pathname15 = "../moreData/upstairs 2by2-1341487835339.dat";
//	static final String pathname16 = "../moreData/up stairs different gait-1341487690544.dat";
//
//	// New data (not in trained dataset)
//	static final String pathname7 = "../walk normal testset -1340372179792.dat";
//	static final String pathname8 = "../walk slow testset -1340372124082.dat";
//	static final String pathname9 = "../walk normal marcos-1340373316892.dat";
//	static final String pathname10 = "../walking fast marcos-1340373365756.dat";
//	static final String pathname11 = "../walk slow marcos-1340373227400.dat";
//	static final String pathname12 = "../moreData/running fast-1341487952376.dat";
//	static final String pathname13 = "../moreData/running normal -1341488003710.dat";
//	static final String pathname14 = "../moreData/up stairs-1341487625065.dat";
//	static final String pathname18 = "../moreData/down stairs 1by1-1341487728579.dat";
//	static final String pathname19 = "../walk-hip-new-1345209330159.dat";
//	static final String pathname20 = "../cycling-1344624358452.dat";	
	
	
	// @attribute class {walking, running, up-stairs, down-stairs}
	public static final String[] CLASSES = {"walking", "running", "up-stairs", "down-stairs", "still"};
	
	static public String timestampToStringDate(long timestamp, String format) {
		Date date = new Date(timestamp);
		
		DateFormat df = new SimpleDateFormat(format);
		String textDate = df.format(date);
		
		return textDate;
	}
	
	/**
	 * Finds the max of an positive array (postive values)
	 * @param array
	 * @return an entry index_max -> max
	 */
	public static Entry<Integer, Double> max(double[] array) {
		double max = 0.0; int i_max=-1;
		for (int i=0; i<array.length; i++) {
			if (array[i]>max) {
				max = array[i];
				i_max = i;
			}
		}
		
		return new SimpleEntry<Integer, Double>(i_max,max);
	}
	
	/**
	 * Smoothing algorithm using the weighted sliding average technique. Which consists of sliding a window 
	 * which computes the average of the neighbors. Precondition : window.length is odd. 
	 * @param values on which to apply the algorithm
	 * @param window
	 * @return the smoothed values
	 */
	public static final double[] slidingAverage(double[] newValues, double[] window) {
		int n =newValues.length;
		double[] newVs = new double[n];
		double avg = 0.0, sum = 0.0;
		for(int i=0;i<n;i++){
			avg=0.0;
			sum=0.0;
			for(int j=0;j<window.length;j++){
				int index = i-(window.length/2)+j;
				if (index>=0 && index < n) {
					avg += window[j]*newValues[index];
					sum += window[j];
				}
			}
			newVs[i] = avg/(double)sum;
		}
		return newVs;
	}
	
	/**
	 * time smoothing constant for low-pass filter
	 * 0 ≤ alpha ≤ 1 ; a smaller value basically means more smoothing
	 * See: http://en.wikipedia.org/wiki/Low-pass_filter#Discrete-time_realization
	 */
	static final double ALPHA = 0.3;
	 
	/**
	 * @see http://en.wikipedia.org/wiki/Low-pass_filter#Algorithmic_implementation
	 */
	public static final double[] lowPass( double[] input) {
		double[] output = new double[input.length];
	    output[0] = input[0];
	    for ( int i=1; i<input.length; i++ ) {
	        output[i] = output[i-1] + ALPHA * (input[i] - output[i-1]);
	    }
	    return output;
	}
	
	public static final void plot(double[][] input) {
		
		XYSeriesCollection data = new XYSeriesCollection();
		for (int j=0;j<input.length;j++) {
			XYSeries s = new XYSeries("XYSeries "+input[j].toString());
			for (int i=0;i<input[j].length;i++) {
				s.add(i,input[j][i]);
			}
			data.addSeries(s);
		}
			
		
		JFreeChart chart = ChartFactory.createXYLineChart(
				 "Line Chart Demo",
				 "X",
				 "Y",
				 data,
				 PlotOrientation.VERTICAL,
				 true,false,false);

		 ChartPanel chartPanel = new ChartPanel(chart);
				 
		JFrame frame = new JFrame("Chart of "+input.toString());

		 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		 frame.getContentPane().add(chartPanel, BorderLayout.CENTER);
		 frame.setSize(600, 600);
		 frame.setVisible(true);
	}
}
